--- FogModifier 迷雾 可见度修正器
local cj = cj
local CreateFogModifierRect = cj.CreateFogModifierRect
local FogModifierStart = cj.FogModifierStart
local FogModifierStop = cj.FogModifierStop
local GetHandleId = cj.GetHandleId
local DestroyFogModifier = cj.DestroyFogModifier
local FogEnable = cj.FogEnable
local FogMaskEnable = cj.FogMaskEnable

local IsFogEnabled = cj.IsFogEnabled
local IsFogMaskEnabled = cj.IsFogMaskEnabled

local IsFoggedToPlayer = cj.IsFoggedToPlayer
local IsMaskedToPlayer = cj.IsMaskedToPlayer
local IsVisibleToPlayer = cj.IsVisibleToPlayer

local IsUnitFogged = cj.IsUnitFogged
local IsUnitMasked = cj.IsUnitMasked
local IsUnitVisible = cj.IsUnitVisible
local IsUnitInvisible = cj.IsUnitInvisible

local map_fog  = setmetatable({
    visible = cj.FOG_OF_WAR_VISIBLE,
    blackFog = cj.FOG_OF_WAR_MASKED,
    warFog = cj.FOG_OF_WAR_FOGGED,
},
{
    __index = function (self,k)
        return self.visible
    end
})

local rct = rect:new( )

local mFog = {
    type = 'module',
    module = 'fog',
    __mode = 'k',
}
---@class cFog
---@field handle handle
local cFog = {
    type = 'class',
    class = 'fog',
    __mode = 'k',
}
cFog.__index = cFog

--- 区域可见度
---@param params table -> player|state|rect|sharedVision|afterUnits
--- - player : player
--- - state : string = visible|blackFog|warFog  对应 可见 黑色迷雾 战争迷雾
--- - rect : rect  区域
--- - sharedVision : bool  可选 共享视野 默认true
--- - afterUnits : bool  可选   默认false
--- - enable : bool 可选 是否启用 默认 true
---
---@return fog
function mFog:rect( params )
    ---@type player
    local p = params.player or player[1]        --玩家

    local state = map_fog [ params.state ]      --可见 黑色迷雾 战争迷雾 对应 visible blackFog warFog

    ---@type rect
    local r = params.rect or rct                    --修正区域

    local sharedVision = params.sharedVision    --共享视野
    if not sharedVision then
        sharedVision = true
    else
        sharedVision = sharedVision and true or false
    end

    local afterUnits = params.afterUnits and true or false --

    local enable = params.enable
    if not enable then
        enable = true
    else
        enable = enable and true or false
    end

    rct:copy( r )

    --创建后 移动区域不影响可见修正器
    local h = CreateFogModifierRect( p.handle, state, rct.handle, sharedVision, afterUnits )
    ---@class fog : cFog
    local obj = {
        handle = h,
        h = GetHandleId(h),

        player = p,
        state = params.state,
        sharedVision = sharedVision,
        enabled = false,

    }
    setmetatable( obj, cFog )

    if enable then
        obj:enable(true)
    end

    return obj
end

--- 销毁可见修正器
function cFog:del()
    DestroyFogModifier( self.handle )
    setmetatable( self, nil )
    self.handle = nil
    self.hid = 0
end

--- 启用/禁用 可见修正器
function cFog:enable( enable )
    self.enabled = enable and true or false
    local func = enable and FogModifierStart or FogModifierStop
    func( self.handle )
end

--- 修改 世界 战争迷雾
function mFog:WarFog( flag )
    flag = flag and true or false
    FogEnable( flag )
    self._isWarFogEnabled = flag
end

--- 修改 世界 黑色迷雾
function map_fog:blackFog( flag )
    flag = flag and true or false
    FogMaskEnable( flag )
    self._isBlackFogEnabled = flag
end

local function isWarFogEnabled(self)
    return self._isWarFogEnabled
end

function mFog:isWarFogEnabled()
    self._isWarFogEnabled = IsFogEnabled()
    self.isWarFogEnabled = isWarFogEnabled
    return self._isWarFogEnabled
end

local function isBlackFogEnabled(self)
    return self._isBlackFogEnabled
end

function mFog:isBlackFogEnabled()
    self._isBlackFogEnabled = IsFogMaskEnabled()
    self.isBlackFogEnabled = isBlackFogEnabled
    return self._isBlackFogEnabled
end

--- 点是否对玩家来说在战争迷雾中
---@param x real
---@param y real
---@param p player
---@return bool
function mFog:isWarFoggedToPlayer( x, y, p )
    return IsFoggedToPlayer( x, y, p.handle )
end

--- 点是否对玩家来说在黑色迷雾中
---@param x real
---@param y real
---@param p player
---@return bool
function mFog:isBlackFoggedToPlayer( x, y, p )
    return IsMaskedToPlayer( x, y, p.handle )
end

--- 点是否对玩家可见
---@param x real
---@param y real
---@param p player
---@return bool
function mFog:isVisibleToPlayer( x, y, p )
    return IsVisibleToPlayer( x, y, p.handle )
end

--- 单位是否对玩家来说处于战争迷雾中
---@param u unit
---@param p player
---@return bool
function mFog:isUnitWarFoggedToPlayer( u, p )
    return IsUnitFogged( u.handle, p.handle )
end

--- 单位是否对玩家来说处于黑色迷雾中
---@param u unit
---@param p player
---@return bool
function mFog:isUnitBlackFoggedToPlayer( u, p )
    return IsUnitMasked( u.handle, p.handle )
end

--- 单位是否对玩家来说可见
---@param u unit
---@param p player
---@return bool
function mFog:isUnitVisibleToPlayer( u, p )
    return IsUnitVisible( u.handle, p.handle )
end

--- 单位是否对玩家来说不可见
---@param u unit
---@param p player
---@return bool
function mFog:isUnitInvisibleToPlayer( u, p )
    return IsUnitInvisible( u.handle, p.handle )
end

return mFog